/* 
 */
# ifndef LIB_WOLDS
# define LIB_WOLDS

# include <string>
# include <iostream>

/* Елемент массива
 * слово
 * указатель на предедущий элемент
 * указатель на слежующий элемент
 * 
 * 
 */
struct Word
{
  /* пример использования: Words, ... */
  
  /* слово: */
  std::string value;
  
  /* данные для операций: */
  Word *prev;
  Word *next;
  
  Word ()
  {
    /* это слово последнее и первое */
    this->next = NULL;
    this->prev = NULL;
  }
};





/* Массив слов
 * указатель на первый элемент
 * указатель на последний элемент
 * 
 * функции обработки элементов
 */
class Words
{
  /* пример использования: ... */
 
  /* указатели на начало и конец слов */
  private:
    
    Word *head;
    Word *tail;
  
  
  /* */
  public:    
    
    
    Words ()
    {
      this->head = NULL;
      this->tail = NULL;
    }


    /* добавить значение-слово в слова */
    void
    operator+ (char *value)
    {
      this->operator+ (std::string (value));
    }
    
    /* добавить значение-слово в слова */
    void
    operator+ (std::string value)
    {
      Word word;
      word.value = value;
      
      this->operator+ (&word);
    }    
        
    /* добавить слово в слова */
    void
    operator+ (Word *word)
    {
      if (this->tail != NULL)
        {
          std::cout << "add other element" << std::endl;
          
          /* новое слово указывает следующим массив слов */
          word->next = this->head;
          
          /* первое слово массива слов указывает на новое первое слово  */
          this->tail->prev = word;
          
          /* ссыляемся на новое первое слово массив слов */
          this->tail = word;
        }
      else
        {
          std::cout << "add first element" << std::endl;

          /* ссыляемся на новое первое слово массив слов */
          this->tail = word;
          this->head = word;
        }
    }
    

    
        
    /* удалить слово из слов */
    void
    del (const char *value)
    {
      std::string word(value);
      
      this->del(word);
    }
    
    
    /* удалить слово из слов */
    void
    del (std::string value)
    {
      for
        (
          /* начать с первого */
          Word *i = this->head;
          
          /* пока следующего не будет */
          i->next != NULL;
          
          /* перейти на следующий */
          i = i->next
        )
        {
          /* если слово равно слову которое нужно удалить: */
          if (i->value == value)
            {
              /* предыдущим элементом указываем на следующий, а не на текущий */
              i->prev->next = i->next;
              
              /* следующим элементом указываем на предыдущий, а не на текущий */
              i->next->prev = i->prev;
              
              /* элементы больше не указывают на этот элемент
               * удаляем:
               */
              delete i;
              
              /* мы убрали слово (которое искали)
               * выходим:
               */
              break;
            }
        }
    }    
    
    
    /* искать индекс этого слова в словах */
    int
    search (const char *value)
    {
      return this->search (std::string (value));
    }
    
    /* искать индекс этого слова в словах */
    int
    search (std::string value)
    {
      /* счетчик: */
      int count = 0;
      
      for
        (
          /* начать с первого */
          Word *i = this->head;
          
          /* пока следующего не будет */
          i != this->tail;
          
          /* перейти на следующий */
          i = i->next,
          /* увеличивать просматриваемых элементов */
          count++
        )
        {
          if (i->value == value)
            return count;
        }
        
      return -1;    
    }
    
    /* слова имеется в словах? */
    bool
    find (Word &word)
    {    
      for
        (
          /* начать с первого */
          Word *i = this->head;
          
          /* пока следующего не будет */
          i->next != NULL;
          
          /* перейти на следующий */
          i = i->next
        )
        
          if (i->value == word.value)
            return true;

      return false;
    }
    
    /* добавить если не найден */
    void
    append (Word &word)
    {
      if (!this->find (word.value))
        this->operator +(&word)
    }
    
    
    /* удалить все это слово */
    voidt
    dels (Word &word)
    {
      for (Word *i = head; i->next != NULL; i = i->next)
        if (i->value == word.value)
          {
            i->prev->next = i->next;  
            i->next->next = i->prev;

            delete i;
          }
    }
    
    
    /* получить одно первое слово */
    Word*
    get ()
    {
      return this->head;
    }
    
    
    void
    save ()
    {
      while (i = words.pull() == NULL)
        system("echo " + i.c_str() + " >> " + file);
    }
    
    
    void
    load (int argn, char* args)
    {
      this->clear();
      
      for (int i=0;i<argn;i++)
        this->add(i);
    }
    
  /* additional */
  public:
    
    
    /* */
    void
    clear ()
    {
    }
    
    /* вывести слова */
    void
    print ()
    {
      int count = 0;
      
      for
        (
          /* начать с первого */
          const Word *i = this->head;
          
          /* пока следующего не будет */
          i->next != NULL;
          
          /* перейти на следующий */
          i = i->next,
          
          
          count++
        )
        {
          std::cout << i->value << " " << count << " ";
        }
        
        std::cout << std::endl;
    }
};


# endif /* LIB_WOLDS */

